package com.zx._05_代理.cglibProxy;

import java.lang.reflect.Method;
import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;

@Slf4j
public class Main {

    public static void main(String[] args) {
        //normal();

        multiple();
    }

    /**
     * 只增强一个代理类
     */
    private static void normal() {
        Enhancer enhancer = new Enhancer();
        // 配置目标类
        enhancer.setSuperclass(RealSubject.class);
        // 配置代理类
        enhancer.setCallback(new MyIntercept());
        // 创建代理对象
        RealSubject real = (RealSubject) enhancer.create();
        // 执行方法
        real.run();
        // real.class=class com.zx._05_代理.cglibProxy.RealSubject$$EnhancerByCGLIB$$36e2bca2
        log.info("real.class={}", real.getClass());
    }

    /**
     * 多重代理
     */
    private static void multiple() {
        Enhancer enhancer = new Enhancer();
        // 配置目标类
        enhancer.setSuperclass(RealSubject.class);
        // 配置多个代理类
        enhancer.setCallbacks(new MethodInterceptor[]
                {new MyIntercept(), new MyIntercept2(), new MyIntercept3()}
        );
        // 使用CallbackFilter调用不同的方法，调用不同的代理方法
        enhancer.setCallbackFilter(new CallbackFilter() {
            @Override
            public int accept(Method method) {
                if (method.getName().equals("run")) {
                    return 0;
                } else if (method.getName().equals("run1")) {
                    return 1;
                } else if (method.getName().equals("run2")) {
                    return 2;
                } else {
                    return 0;
                }
            }
        });
        // 创建代理对象
        RealSubject real = (RealSubject) enhancer.create();
        // real.class=class com.zx._05_代理.cglibProxy.RealSubject$$EnhancerByCGLIB$$36e2bca2
        log.info("real.class={}", real.getClass());
        // 执行方法
        real.run();
        // 执行方法
        real.run1();
        // 执行方法
        real.run2();
        // 执行方法
        real.run3();
    }
}
